package com.stylefeng.guns.modular.charon.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.stylefeng.guns.common.exception.BizExceptionEnum;
import com.stylefeng.guns.common.exception.BussinessException;
import com.stylefeng.guns.common.persistence.dao.PcServerInfoMapper;
import com.stylefeng.guns.common.persistence.model.PcServerInfo;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.CheckTip;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.modular.charon.cdkey.SNFactory;
import com.stylefeng.guns.modular.charon.service.IPcServerInfoService;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Map;

/**
 * PC信息维护控制器
 *
 * @author fengshuonan
 * @Date 2018-02-02 10:59:14
 */
@Controller
@RequestMapping("/pcServerInfo")
@ConfigurationProperties(prefix = PcServerInfoController.GUNS_PREFIX)
public class PcServerInfoController extends BaseController {
    protected final static Logger logger = LoggerFactory.getLogger(PcServerInfoController.class);
    private String PREFIX = "/charon/pcServerInfo/";
    public static final String GUNS_PREFIX = "guns";

    @Value("${guns.cloudServerUrl}")
    String cloudServerUrl;

    @Autowired
    private IPcServerInfoService pcServerInfoService;
    @Resource
    PcServerInfoMapper pcServerInfoMapper;

    /**
     * 跳转到PC信息维护首页
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "pcServerInfo.html";
    }

    /**
     * 跳转到添加PC信息维护
     */
    @RequestMapping("/pcServerInfo_add")
    public String pcServerInfoAdd() {
        return PREFIX + "pcServerInfo_add.html";
    }

    /**
     * 跳转到修改PC信息维护
     */
    @RequestMapping("/pcServerInfo_update/{pcServerInfoId}")
    public String pcServerInfoUpdate(@PathVariable String pcServerInfoId, Model model) {
        PcServerInfo pcServerInfo = pcServerInfoMapper.queryById(pcServerInfoId);
        model.addAttribute("item", pcServerInfo);
        return PREFIX + "pcServerInfo_edit.html";
    }

    /**
     * 获取PC信息维护列表
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(String serverName, String ip, String status) {
        return pcServerInfoMapper.list(serverName, ip, status);
    }

    /**
     * 新增PC信息维护
     */
    @RequestMapping(value = "/add")
    @ResponseBody
    public Object add(PcServerInfo pcServerInfo) {
        String machineCode = pcServerInfo.getMachineCode();
        Map<String, String> ipMap = pcServerInfoMapper.checkMachineCodeUnique(machineCode);
        if ("N".equals(ipMap.get("isUnique"))) {
            throw new BussinessException(BizExceptionEnum.MACHINE_CODE_IS_NOT_UNIQUE);
        }

        String key = SNFactory.getSN(machineCode);
        String account = ShiroKit.getUser().getAccount();

        pcServerInfo.setId(IdWorker.get32UUID());
        pcServerInfo.setCdkey(key);
        pcServerInfo.setCreatTime(new Date());
        pcServerInfo.setUpdateTime(new Date());
        pcServerInfo.setCreateUser(account);
        pcServerInfo.setUpdateUser(account);
        pcServerInfo.setStatus("1");
        pcServerInfo.insert();
        return super.SUCCESS_TIP;
    }

    /**
     * 禁用PC信息维护
     */
    @RequestMapping(value = "/disableSwitch")
    @ResponseBody
    public Object disableSwitch(String id, String status) {
        PcServerInfo pcServerInfo = new PcServerInfo();
        pcServerInfo.setId(id);
        pcServerInfo.setStatus(status);
        pcServerInfo.updateById();
        return SUCCESS_TIP;
    }

    /**
     * 修改PC信息维护
     */
    @RequestMapping(value = "/update")
    @ResponseBody
    public Object update(PcServerInfo pcServerInfo) {

        String id = pcServerInfo.getId();
        String mCode = pcServerInfo.getMachineCode();
       /* if (ToolUtil.isOneEmpty(id, mCode)) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        Map<String, String> ipMap = pcServerInfoMapper.checkIpUnique(ip);
        *//*if ("N".equals(ipMap.get("isUnique"))) {
            throw new BussinessException(BizExceptionEnum.IP_IS_NOT_UNIQUE);
        }*//*

        Map<String, String> map = pcServerInfoMapper.checkIpChange(ip, id);
        if ("Y".equals(map.get("isChange"))) {
            pcServerInfo.setCdkey(SNFactory.getSN(ip));
        }*/
        pcServerInfo.setCdkey(SNFactory.getSN(mCode));
        pcServerInfo.setUpdateTime(new Date());
        pcServerInfo.setUpdateUser(ShiroKit.getUser().account);
        pcServerInfoService.updateById(pcServerInfo);
        return super.SUCCESS_TIP;
    }

    /**
     * 下载lic文件
     */
    @RequestMapping(value = "/downloadLic")
    @ResponseBody
    public Object downloadLic(String id, HttpServletRequest request, HttpSession session) {

        String webRootPath = this.getClass().getResource("/").
                getPath();

        String path = "static/lic/" + id.trim() + "/";
        String fileName = "em.lic";
        PcServerInfo pcServerInfo = new PcServerInfo();
        pcServerInfo.setId(id);
        pcServerInfo = pcServerInfo.selectById();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("ip", pcServerInfo.getIp());
        jsonObject.put("port", pcServerInfo.getPort());
        jsonObject.put("key", pcServerInfo.getCdkey());
        jsonObject.put("cloudServerUrl", cloudServerUrl);
        jsonObject.put("validationType",pcServerInfo.getValidationType() );
        OutputStream fileOutputStream = null;
        try {
            File file = new File(webRootPath + path + fileName);
            if (!file.exists()) {
                File dir = new File(file.getParent());
                dir.mkdirs();
                file.createNewFile();
            }
            fileOutputStream = new FileOutputStream(file);
            IOUtils.write(jsonObject.toJSONString(), fileOutputStream);
            return path + fileName;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(fileOutputStream);
        }
        return super.ERROR;

    }
    //3.1版本
    @RequestMapping(value = "/checkLicence2")
    @ResponseBody
    public Object checkLicence2(@RequestBody JSONObject userEntity, HttpServletRequest request) {

        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
            ipAddress = ipAddress.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ipAddress;

//            JSONObject json = JSONObject.parseObject(lic);
            JSONObject json = userEntity;
            String actMachineCode = json.getString("machineCode"); //机器码
            String ip = json.getString("ip");
            String cdkey = json.getString("key");   // LIC

            if (!ipAddress.equals(ip)) {
                logger.info("注册IP："+ip+",实际IP："+ipAddress+",Licence中的ip和实际服务器ip不符，请确认注册的ip是外网ip");
                return new ErrorTip(400, "Licence中的ip和实际服务器ip不符，请确认注册的ip是外网ip");
            }
            PcServerInfo pcServerInfo = new PcServerInfo();

            int count = pcServerInfo.selectCount("machine_code={0} and cdkey={1}", actMachineCode, cdkey);
            if (count > 0) {
                logger.info("认证成功IP："+ip+",machineCcode:"+actMachineCode+",cdkey:"+cdkey);
                return new CheckTip(cdkey);
            }else{
                logger.info("注册IP："+ip+",实际IP："+ipAddress+",Licence中的ip和实际服务器ip不符，请确认注册的ip是外网ip");
                return new ErrorTip(400, "非法证书,注册IP和授权码不符!");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ErrorTip(500, "未知错误");
    }
    //V3.0版本
    @RequestMapping(value = "/checkLicence")
    @ResponseBody
    public Object checkLicence(@RequestBody JSONObject userEntity, HttpServletRequest request) {

        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
            ipAddress = ipAddress.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ipAddress;

//            JSONObject json = JSONObject.parseObject(lic);
            JSONObject json = userEntity;
            String ip = json.getString("ip");
            String cdkey = json.getString("key");

            if (!ipAddress.equals(ip)) {
                return new ErrorTip(400, "Licence中的ip和实际服务器ip不符，请确认注册的ip是外网ip");
            }
            PcServerInfo pcServerInfo = new PcServerInfo();

            int count = pcServerInfo.selectCount("ip={0} and cdkey={1}", ip, cdkey);
            if (count > 0) {
                logger.info("认证成功IP："+ip+",cdkey:"+cdkey);
                return new CheckTip(cdkey);
            }else{
                return new ErrorTip(400, "非法证书,注册IP和授权码不符!");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ErrorTip(500, "未知错误");
    }
}
